#!/usr/bin/env python
# encoding: utf-8

import random

class Jugador(object):
    """ Clase abstracta en la que se basan los jugadores. """

    nombre = ""
    descripcion = ""
    autor = ""

    def __init__(self):
        self.criaturas = []

    def agregar_criatura(self, criatura):
        self.criaturas.append(criatura)

    def eliminar_criatura(self, criatura):
        self.criaturas.remove(criatura)

    def elegir_criatura(self):
        if self.criaturas:
            return self.criaturas[-1]
        return None

    def elegir_accion(self, criatura):
        pass

    def habilidad_satisface_costos(self, estado, habilidad):
        costos = habilidad.obtener_costos()
        for clave, valor in costos.iteritems():
            if not clave in estado or estado[clave] < valor:
                return False

        return True
        

    def __str__(self):
        return "%s, por %s\n%s\nCon: %s" % (
            self.nombre, self.autor, self.descripcion, self.criaturas)


class JugadorCobarde(Jugador):

    autor = "Marga"
    nombre = "Marga-Cobarde"
    descripcion = "Un jugador que elige aleatoriamente y si no la puede usar, huye"

    def elegir_accion(self, origen, destino):
        """ Elige una acción dentro de las posibles. """

        # Elige una habilidad al azar, sino cumple los costos, huye
        habilidades = origen.obtener_habilidades()
        elegida = random.choice(habilidades.keys())

        # Esta funcion esta en la criatura, pero no se la puede usar porque
        # no fue especificada
        if not self.habilidad_satisface_costos(origen.obtener_estado(), habilidades[elegida]):
            return "huir", None

        # Suma las consecuencias en el destino, 
        # si son positivas pone la criatura origen como destino
        consecuencias = habilidades[elegida].obtener_consecuencias(origen, destino)
        total = sum(consecuencias[1].values())
        if total > 0:
            return elegida, origen
        return elegida, destino
            
   
class JugadorRandom(Jugador):

    autor = "Marga"
    nombre = "Marga-Random"
    descripcion = "Un jugador que elige aleatoriamente, si no la puede usar, busca otra"

    def elegir_accion(self, origen, destino):
        """ Elige una acción dentro de las posibles. """

        # Elige una habilidad al azar, sino cumple los costos, huye
        habilidades = origen.obtener_habilidades()
        
        elegida = random.choice(habilidades.keys())
        contador = 0
        while not self.habilidad_satisface_costos(origen.obtener_estado(), habilidades[elegida]):
            contador += 1
            if contador > len(habilidades): break
            elegida = random.choice(habilidades.keys())

        # Suma las consecuencias en el destino, 
        # si son positivas pone la criatura origen como destino
        consecuencias = habilidades[elegida].obtener_consecuencias(origen, destino)
        total = sum(consecuencias[1].values())
        if total > 0:
            return elegida, origen
        return elegida, destino
 

class JugadorInteligente(Jugador):

    autor = "Marga"
    nombre = "Marga-Inteligente"
    descripcion = "Un jugador que trata de elegir lo que más le conviene"

    def __init__(self):
        Jugador.__init__(self)
        self.usos = {}

    def elegir_criatura(self):
        if self.criaturas:
            if sum(self.criaturas[-1].obtener_estado().values()) > 130:
                habilidades = self.criaturas[-1].obtener_habilidades()
                for n, habilidad in habilidades.items():
                    consecuencias = habilidad.obtener_consecuencias(self.criaturas[-1], self.criaturas[-1])
                    if sum(consecuencias[1].values()) > 0:
                        self.usos[self.criaturas[-1]] = self.usos.get(self.criaturas[-1],1)+1
                        if self.usos[self.criaturas[-1]] - self.criaturas[-1].obtener_estado()["xp"] < 12:
                            return self.criaturas[-1]
        self.criaturas = []
        return None

    def elegir_accion(self, origen, destino):

        habilidades = origen.obtener_habilidades()
        estado = origen.obtener_estado()
        estado_dest = destino.obtener_estado()

        comp_pos = cmp
        comp_neg = lambda x,y: (-1)*cmp(x,y)

        max_pos = 0; min_neg = 0
        elegida_pos = "huir"; elegida_neg = "huir"

        for nombre, habilidad in habilidades.items():
            if self.habilidad_satisface_costos(estado, habilidad):
                consecuencias = habilidad.obtener_consecuencias(origen, destino)
                total = sum(consecuencias[1].values())
                if total > max_pos:
                    elegida_pos = nombre
                    max_pos = total
                if total < min_neg:
                    elegida_neg = nombre
                    min_neg = total


        elegida = elegida_neg
        criatura = destino

        if estado["hp"] < 15 and \
            (min_neg*(-1) < estado_dest["hp"]) and \
            max_pos > 0:

            elegida = elegida_pos
            criatura = origen
        
        return elegida, criatura


# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
